package com.umessage.hotel.service.impl;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.umessage.common.service.RedisService;
import com.umessage.hotel.dao.WxMsgTmplMapper;
import com.umessage.hotel.domain.HotelInfo;
import com.umessage.hotel.domain.MemberInvoice;
import com.umessage.hotel.domain.OrderBreakfast;
import com.umessage.hotel.domain.OrderInfo;
import com.umessage.hotel.domain.RoomInfo;
import com.umessage.hotel.domain.TemplateMessage;
import com.umessage.hotel.domain.WxCfg;
import com.umessage.hotel.domain.WxMsgTmpl;
import com.umessage.hotel.service.FormService;
import com.umessage.hotel.service.HotelInfoService;
import com.umessage.hotel.service.RoomInfoService;
import com.umessage.hotel.service.WXUserMemberService;
import com.umessage.hotel.service.WXUserService;
import com.umessage.hotel.service.WxCfgService;
import com.umessage.hotel.service.WxMsgTmplService;
import com.umessage.hotel.util.HttpUtil;

@Service
public class WxMsgTmplServiceImpl implements WxMsgTmplService {

	@Autowired
	private WxCfgService wxCfgService;
	@Autowired
	private RedisService redisService;
	@Autowired
	private WxMsgTmplMapper wxMsgTmplMapper;
	@Autowired
	private WXUserMemberService wxUserMemberService;
	@Autowired
	private WXUserService wxUserService;
	@Autowired
	private HotelInfoService hotelInfoService;
	@Autowired
	private FormService formService;
	@Autowired
	private RoomInfoService roomInfoService;

	private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

	public String getAccessToken(String hotelId, String appType) {

		String key = "access_token_" + hotelId + appType;
		String token = redisService.get(key);

		if (token == null) {
			WxCfg wxcfg = wxCfgService.queryWxCfg(hotelId, appType);
			String url = "https://api.weixin.qq.com/cgi-bin/token?appid=" + wxcfg.getAppId() + "&secret="
					+ wxcfg.getSecretKey() + "&grant_type=client_credential";

			JSONObject session = HttpUtil.sendGet(url, null);
			System.out.println(session);
			token = session.getString("access_token");
			if (token == null) {
				throw new RuntimeException("get access token encounted error");
			}
			System.out.println("access_token=" + token);
			Long expires_in = session.getLong("expires_in");// 秒
			redisService.set(key, token);
			redisService.pexpire(key, expires_in * 1000);
		}

		return token;
	}

	@Override
	public void getTemplateLibraryList(String hotelId, String appType, String templateId) {

		String token = getAccessToken(hotelId, appType);

		String url = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/list?access_token=" + token;
		System.out.println(url);

		JSONObject params = new JSONObject();
		params.put("offset", 0);
		params.put("count", 20);

		JSONObject json = HttpUtil.sendGet(url, params.toJSONString());

		System.out.println(json);

	}

	@Override
	public void sendTemplateMessage(TemplateMessage message) {
		
		if(StringUtils.isBlank(message.getTouser())) {
			throw new RuntimeException("touser can not be null");
		}
		
		if(StringUtils.isBlank(message.getFormid())) {
			String formId = formService.getValidFormId(message.getTouser());
			message.setFormid(formId);
		}
		
		if(StringUtils.isBlank(message.getFormid())) {
			throw new RuntimeException("formid can not be null");
		}
		
		if(StringUtils.isBlank(message.getPage())) {
			message.setPage("wxxq/view/home/index/index");
		}
		

		String appType = "1";// 客户端小程序
		WxCfg wxcfg = wxCfgService.queryWxCfg(message.getHotelId(), appType);
		if (wxcfg == null) {
			throw new RuntimeException("没有找到该酒店对应的小程序配置");
		}
		WxMsgTmpl wxMsgTmpl = wxMsgTmplMapper.findHotelMiniProgramMsgTmpl(message.getHotelId(), wxcfg.getAppId(),
				message.getTemplateTitleId());
		if (wxMsgTmpl == null) {
			throw new RuntimeException("酒店没有配置"+ message.getHotelId() +"============="+ message.getTemplateTitleId() + "消息模版");
		}

		String accessToken = getAccessToken(message.getHotelId(), appType);
		String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + accessToken;

		JSONObject params = new JSONObject();
		params.put("touser", message.getTouser());
		params.put("template_id", wxMsgTmpl.getTemplateId());
		params.put("page", message.getPage());
		params.put("form_id", message.getFormid());
		
		if(message.getData() != null) {
			params.put("data", message.getData());
		} else if (message.getParams() != null && message.getParams().size() > 0) {
			JSONObject obj = new JSONObject();
			for (int i = 0; i < message.getParams().size(); i++) {
				// 酒店名称
				JSONObject value = new JSONObject();
				value.put("value", message.getParams().get(i));
				int index = i + 1;
				obj.put("keyword" + index, value);
			}
			params.put("data", obj);
		}

		JSONObject json = HttpUtil.sendGet(url, params.toJSONString());
		if (json != null && !"0".equals(json.getString(("errcode")))) {
			System.out.println("send weixin template message error:" + json.getString("errmsg"));
		} else if (json != null) {
			System.out.println(json);
		}
	}

	@Override
	public void sendOrderPaySuccessMsg(OrderInfo order) {

		try {

			TemplateMessage message = new TemplateMessage();
			message.setHotelId(String.valueOf(order.getHotelId()));
			message.setTemplateTitleId("AT0009");
			message.setTouser(order.getOpenid());
			message.setFormid(order.getPrepayId());

			HotelInfo hotel = hotelInfoService.selectByKey(String.valueOf(order.getHotelId()));
			// 酒店名称
			// {{keyword1.DATA}}
			// 入住时间
			// {{keyword2.DATA}}
			// 退房时间
			// {{keyword3.DATA}}
			// 金额
			// {{keyword4.DATA}}
			// 间数
			// {{keyword5.DATA}}

//			JSONObject obj = new JSONObject();
//			// 酒店名称
//			JSONObject value1 = new JSONObject();
//			value1.put("value", hotel.getHotelName());
//			obj.put("keyword1", value1);
//			// 入住时间
//			JSONObject value2 = new JSONObject();
//			value2.put("value", df.format(df.parse(order.getCheckinTime())));
//			obj.put("keyword2", value2);
//			// 退房时间
//			JSONObject value3 = new JSONObject();
//			value3.put("value", df.format(df.parse(order.getCheckoutTime())));
//			obj.put("keyword3", value3);
//			// 金额
//			JSONObject value4 = new JSONObject();
//			value4.put("value", order.getTotalPrice().toString() + "元");
//			obj.put("keyword4", value4);
//			// 间数
//			JSONObject value5 = new JSONObject();
//			value5.put("value", order.getRoomCount());
//			obj.put("keyword5", value5);
//			message.setData(obj);
			
			List<String> paras = new ArrayList<String>();
			paras.add(order.getOrderSn());
			paras.add(hotel.getHotelName());
			paras.add(df.format(df.parse(order.getCheckinTime())));
			paras.add(df.format(df.parse(order.getCheckoutTime())));
			paras.add(order.getTotalPrice().toString() + "元");
			paras.add(String.valueOf(order.getRoomCount()));
			message.setParams(paras);

			sendTemplateMessage(message);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public void sendCancelOrderMsg(OrderInfo order) {
		try {
			TemplateMessage message = new TemplateMessage();
			message.setHotelId(String.valueOf(order.getHotelId()));
			message.setTemplateTitleId("AT0024");
			message.setTouser(order.getOpenid());
			if (order.getPayType() > 1 && order.getPayStatus() > 0) {// 已在线支付
				message.setFormid(order.getPrepayId());
			}
			HotelInfo hotel = hotelInfoService.selectByKey(String.valueOf(order.getHotelId()));

			// 酒店名称
			// {{keyword1.DATA}}
			// 入住时间
			// {{keyword2.DATA}}
			// 离店日期
			// {{keyword3.DATA}}
			// 取消原因
			// {{keyword4.DATA}}
			// 订单金额
			// {{keyword5.DATA}}
//			JSONObject obj = new JSONObject();
//			// 酒店名称
//			JSONObject value1 = new JSONObject();
//			value1.put("value", hotel.getHotelName());
//			obj.put("keyword1", value1);
//			// 入住时间
//			JSONObject value2 = new JSONObject();
//			value2.put("value", df.format(df.parse(order.getCheckinTime())));
//			obj.put("keyword2", value2);
//			// 离店日期
//			JSONObject value3 = new JSONObject();
//			value3.put("value", df.format(df.parse(order.getCheckoutTime())));
//			obj.put("keyword3", value3);
//			// 取消原因
//			JSONObject value4 = new JSONObject();
//			String reason = "由于酒店满房原因，您的订单被取消";
//			if (StringUtils.isNotBlank(order.getCancelReason())) {
//				reason = order.getCancelReason();
//			} else if (order.getCancelType() == 2) {// 用户取消
//				reason = "用户取消";
//			}
//			value4.put("value", reason);
//			obj.put("keyword4", value4);
//			// 金额
//			JSONObject value5 = new JSONObject();
//			value5.put("value", order.getTotalPrice().toString() + "元");
//			obj.put("keyword5", value5);
//			message.setData(obj);
			
			List<String> paras = new ArrayList<String>();
			paras.add(order.getOrderSn());
			paras.add(hotel.getHotelName());
			paras.add(df.format(df.parse(order.getCheckinTime())));
			paras.add(df.format(df.parse(order.getCheckoutTime())));
			String reason = "由于酒店满房原因，您的订单被取消";
			if (StringUtils.isNotBlank(order.getCancelReason())) {
				reason = order.getCancelReason();
			} else if (order.getCancelType() == 2) {// 用户取消
				reason = "用户取消";
			}
			paras.add(reason);
			paras.add(order.getTotalPrice().toString() + "元");
			message.setParams(paras);

			sendTemplateMessage(message);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 发送确认订单消息通知
	 * 
	 * @param order
	 */
	@Override
	public void sendConfirmOrderMsg(OrderInfo order) {
		try {
			TemplateMessage message = new TemplateMessage();
			message.setHotelId(String.valueOf(order.getHotelId()));
			message.setTemplateTitleId("AT0163");
			message.setTouser(order.getOpenid());
			HotelInfo hotel = hotelInfoService.selectByKey(String.valueOf(order.getHotelId()));
			RoomInfo roomInfo = roomInfoService.selectByKey(order.getRoomId());
//			订单号
//			{{keyword1.DATA}}
//			商户名称
//			{{keyword2.DATA}}
//			入住时间
//			{{keyword3.DATA}}
//			离店时间
//			{{keyword4.DATA}}
//			房间信息
//			{{keyword5.DATA}}
			JSONObject obj = new JSONObject();
			// 订单号
			JSONObject value1 = new JSONObject();
			value1.put("value", order.getOrderSn());
			obj.put("keyword1", value1);
			// 酒店名称
			JSONObject value2 = new JSONObject();
			value2.put("value", hotel.getHotelName());
			obj.put("keyword2", value2);
			// 入住时间
			JSONObject value3 = new JSONObject();
			value3.put("value", df.format(df.parse(order.getCheckinTime())));
			obj.put("keyword3", value3);
			// 离店日期
			JSONObject value4 = new JSONObject();
			value4.put("value", df.format(df.parse(order.getCheckoutTime())));
			obj.put("keyword4", value4);
			//房间信息
			JSONObject value5 = new JSONObject();
			if( "1".equals(roomInfo.getPolBreakfast())){
				value5.put("value", order.getName()+" x"+order.getRoomCount());
			}else{
				String brakfast =  "2".equals(roomInfo.getPolBreakfast())? "含早":"含双早";  
				value5.put("value", order.getName()+" x"+order.getRoomCount()+" ("+brakfast+")");
			}
			obj.put("keyword5", value5);
			message.setData(obj);
			sendTemplateMessage(message);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void sendOrderBKFPaySuccessMsg(OrderBreakfast orderbkf) {
		try {
			TemplateMessage message = new TemplateMessage();
			message.setHotelId(orderbkf.getHotelId());
			message.setTemplateTitleId("AT1313");
			message.setTouser(orderbkf.getOpenid());
			message.setFormid(orderbkf.getPrepayId());

			// HotelInfo hotel =
			// hotelInfoService.selectByKey(String.valueOf(orderbkf.getHotelId()));
			// 交易商品
			// {{keyword1.DATA}}
			// 早餐券单价
			// {{keyword2.DATA}}
			// 早餐券有效期
			// {{keyword3.DATA}}
			// 共计张数
			// {{keyword4.DATA}}
			// 共计金额
			// {{keyword5.DATA}}
			 JSONObject obj = new JSONObject(); 
			//交易商品
			 JSONObject value1 = new JSONObject(); 
			 value1.put("value","早餐券");
			 obj.put("keyword1", value1);
			// 早餐券单价
			 JSONObject value2 = new JSONObject();
			 value2.put("value",orderbkf.getUnitPrice()+"元/张");
			 obj.put("keyword2", value2);
			// 早餐券有效期
			 JSONObject value3 = new JSONObject(); 
			 value3.put("value","仅可使用当日有效");
			 obj.put("keyword3", value3);
			// 可用早餐券
			 JSONObject value4 = new JSONObject(); 
			 value4.put("value",orderbkf.getNumDaily()+"张/天");
			 obj.put("keyword4", value4);
			// 共计张数
			 JSONObject value5 = new JSONObject(); 
			 value5.put("value",orderbkf.getAmount()+"张");
			 obj.put("keyword5", value5);
			// 共计金额
			 JSONObject value6 = new JSONObject(); 
			 value6.put("value",orderbkf.getSumPrice()+"元");
			 obj.put("keyword6", value6);
			 
			 message.setData(obj);
			 
			sendTemplateMessage(message);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public void sendOpenInvoice(MemberInvoice invoice) {
		try {
			TemplateMessage message = new TemplateMessage();
			message.setHotelId(invoice.getHotelId()+"");
			message.setTemplateTitleId("AT0234");
			message.setTouser(invoice.getOpenId());
			message.setFormid(invoice.getFromId());

			 JSONObject obj = new JSONObject(); 
			//开票时间
			 JSONObject value1 = new JSONObject(); 
			 value1.put("value",invoice.getCheckoutTime());
			 obj.put("keyword1", value1);
			// 发票抬头
			 JSONObject value2 = new JSONObject();
			 value2.put("value",invoice.getTitle());
			 obj.put("keyword2", value2);
			// 纳税人识别
			 JSONObject value3 = new JSONObject(); 
			 value3.put("value",invoice.getDutyNo());
			 obj.put("keyword3", value3);
			// 备注
			 JSONObject value4 = new JSONObject(); 
			 value4.put("value","已开具发票并邮寄,请注意查收!");
			 obj.put("keyword4", value4);
			 message.setData(obj);
			 
			sendTemplateMessage(message);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
